package sk.pitonak.mhd.ui;

import java.util.ArrayList;
import java.util.Map;

import sk.pitonak.mhd.Database;
import sk.pitonak.mhd.R;
import sk.pitonak.mhd.SimpleCursorLoader;
import sk.pitonak.mhd.U;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

public class HistoryFragment extends ListFragment implements OnItemClickListener,
	OnItemLongClickListener, LoaderCallbacks<Cursor>, ActionMode.Callback, OnCheckedChangeListener {
	private static final int LOADER_ID = 0;
	private static final int MESSAGE_REQUERY = 0;
	private static final int MENU_DELETE = 0;

	private FragmentActivity mActivity;
	private Database mDB;

	private Map<Integer, String> mStops;
	private HistoryAdapter mAdapter;

	private ArrayList<View> mSelection = new ArrayList<View>();
	private ActionMode mActionMode;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		mActivity = getActivity();

		mDB = new Database(mActivity);
		mStops = mDB.getStops();

		mAdapter = new HistoryAdapter(mActivity, null);

		setListAdapter(mAdapter);
		ListView listView = getListView();
		listView.setOnItemClickListener(this);
		listView.setOnItemLongClickListener(this);

		getLoaderManager().initLoader(LOADER_ID, null, this);
	}

	@Override
	public void onResume() {
		super.onResume();
		requery();
	}

	@Override
	public void onDestroy() {
		mDB.close();
		super.onDestroy();
	}

	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
		if(mSelection.isEmpty()) {
			AdapterData data = (AdapterData) view.getTag();
			Intent intent = new Intent(mActivity, ResultActivity.class);
			intent.putExtra(SearchFragment.KEY_FROM, data.from);
			intent.putExtra(SearchFragment.KEY_TO, data.to);
			startActivity(intent);
		}
		else {
			toggleSelection(view);
		}
	}

	@Override
	public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) {
		if(mSelection.isEmpty()) {
			mActionMode = mActivity.startActionMode(this);
			mActivity.onActionModeStarted(mActionMode);
			select(view);
		}
		else {
			toggleSelection(view);
		}
		return true;
	}

	private void toggleSelection(View view) {
		if(mSelection.contains(view)) {
			deselect(view);
		}
		else {
			select(view);
		}
	}

	private void select(View view) {
		mSelection.add(view);
		// TODO:
		((HistoryItem) view).setChecked(true);
	}

	private void deselect(View view) {
		mSelection.remove(view);
		if(mSelection.isEmpty()) mActionMode.finish();
		// TODO:
		((HistoryItem) view).setChecked(false);
	}

	private void clearSelection() {
		for(View view : mSelection) {
			((HistoryItem) view).setChecked(false);
		}
		mSelection.clear();
	}

	private void deleteSelection() {
		U.performOnBackgroundThread(new Runnable() {
			@Override
			public void run() {
				Database database = new Database(mActivity);
				for(View view : mSelection) {
					database.removeFromHistory(((AdapterData) view.getTag()).id);
				}
				database.close();
				mHandler.sendEmptyMessage(MESSAGE_REQUERY);
			}
		});
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, final boolean isChecked) {
		final long id = ((AdapterData) ((View) buttonView.getParent()).getTag()).id;
		U.performOnBackgroundThread(new Runnable() {
			@Override
			public void run() {
				Database database = new Database(mActivity);
				if(database.setFavoriteHistory(id, isChecked)) {
					mHandler.sendEmptyMessage(MESSAGE_REQUERY);
				}
				database.close();
			}
		});
	}

	@Override
	public boolean onCreateActionMode(ActionMode mode, Menu menu) {
		menu.add(0, MENU_DELETE, 0, "Delete")
			.setIcon(R.drawable.ic_menu_delete)
			.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
		return true;
	}

	@Override
	public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
		return false;
	}

	@Override
	public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
		switch(item.getItemId()) {
			case MENU_DELETE:
				deleteSelection();
				return true;
			default:
				Toast.makeText(mActivity, "clicked " + item, Toast.LENGTH_SHORT).show();
				return false;
		}
	}

	@Override
	public void onDestroyActionMode(ActionMode mode) {
		mActionMode = null;
		clearSelection();
	}

	private void requery() {
		getLoaderManager().restartLoader(LOADER_ID, null, this);
	}

	@Override
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		return new SimpleCursorLoader(mActivity) {
			@Override
			public Cursor loadInBackground() {
				Cursor cursor = mDB.queryHistory();
				if(cursor != null) {
					// Ensure the cursor window is filled
					cursor.getCount();
					registerContentObserver(cursor);
				}
				return cursor;
			}
		};
	}

	@Override
	public void onLoaderReset(Loader<Cursor> loader) {
		mAdapter.swapCursor(null);
	}

	@Override
	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
		mAdapter.swapCursor(cursor);
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			if(mActionMode != null) mActionMode.finish();
			requery();
		};
	};

	private class HistoryAdapter extends CursorAdapter {
		private LayoutInflater mInflater;

		public HistoryAdapter(Context context, Cursor cursor) {
			super(context, cursor, 0);
			mInflater = LayoutInflater.from(context);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			View view = mInflater.inflate(R.layout.item_history, null);
			view.setTag(new AdapterData());
			bindView(view, context, cursor);
			return view;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			AdapterData data = (AdapterData) view.getTag();
			data.from = mStops.get(cursor.getInt(0));
			data.to = mStops.get(cursor.getInt(1));
			data.id = cursor.getLong(3);

			((TextView) view.findViewById(R.id.text_from)).setText(data.from);
			((TextView) view.findViewById(R.id.text_to)).setText(data.to);
			CheckBox box = (CheckBox) view.findViewById(R.id.indicator_favorite);
			box.setOnCheckedChangeListener(HistoryFragment.this);
			int checked = cursor.getInt(2);
			box.setChecked(checked != 0);
		}
	}

	private static class AdapterData {
		public String from;
		public String to;
		public long id;
	}
}
